//
//  HTFlexibleView.swift
//  MagaCore
//
//  Created by MrMessy on 2023/5/7.
//

import SwiftUI

struct HTFlexibleView<Data: Collection, Content: View>: View where Data.Element: Hashable {
  var var_data: Data
  var var_spacing: CGFloat
  var var_alignment: HorizontalAlignment
  var var_limitRowsNumber: Int = 5
  var var_content: (Data.Element) -> Content
  @State private var var_rows: [[Data.Element]] = [[]]
  @State private var var_availableWidth: CGFloat = 0
  @State private var var_isExpand: Bool = false
  @State var var_elementsSize: [Data.Element: CGSize] = [:]

  var body : some View {
    ZStack(alignment: Alignment(horizontal: var_alignment, vertical: .center)) {
      Color.clear
        .frame(height: 1)
        .ht_readSize { size in
          var_availableWidth = size.width
        }

      if (var_rows.count > 2) {
        if (var_isExpand) {
          VStack(alignment: var_alignment, spacing: var_spacing) {
            ForEach(Array(var_rows.enumerated()), id: \.element) { index, rowElements in
              HStack(spacing: var_spacing) {
                ForEach(Array(rowElements.enumerated()), id: \.element) { idx, element in
                  if (index == var_rows.count - 1 && idx == rowElements.count - 1) {
                    HStack{
                      Image("arrow_up")
                        .frame(width: 8, height: 8)
                    }
                    .frame(width: 53, height: 26)
                    .background(Color.black.opacity(0.04))
                    .clipShape(Capsule())
                    .onTapGesture {
                      var_isExpand = false
                    }
                  } else {
                    var_content(element)
                  }
                }
              }
            }
          }
        } else {
          VStack(alignment: var_alignment, spacing: var_spacing) {
            ForEach(0..<var_rows.count, id: \.self) { index in
              let rowElements = var_rows[index]
              if (index <= 1 && var_rows.count > 2) {
                HStack(spacing: var_spacing) {
                  ForEach(0..<rowElements.count, id: \.self) { idx in
                    if (index == 1 && idx == rowElements.count - 1) {
                      HStack{
                        Image("arrow_down")
                          .frame(width: 8, height: 8)
                      }
                      .frame(width: 53, height: 26)
                      .background(Color.black.opacity(0.04))
                      .clipShape(Capsule())
                      .onTapGesture {
                        var_isExpand = true
                      }
                    } else {
                      var_content(rowElements[idx])
                    }
                  }
                }
              }
            }
          }
        }
      } else {
        VStack(alignment: var_alignment, spacing: var_spacing) {
          ForEach(Array(var_rows.enumerated()), id: \.element) { index, rowElements in
            HStack(spacing: var_spacing) {
              ForEach(Array(rowElements.enumerated()), id: \.element) { idx, element in
                var_content(element)
              }
            }
          }
        }
      }
    }
    .onAppear{
      var_rows = ht_computeRows()
    }
  }

  func ht_computeRows() -> [[Data.Element]] {
    var var_rows_data: [[Data.Element]] = [[]]
    var var_currentRow = 0
    var var_remainingWidth = var_availableWidth

    for element in var_data {
      let elementSizeWidth = ht_getTextWidth(text: element as! String)

      if var_remainingWidth - (elementSizeWidth + var_spacing) >= 0 {
        var_rows_data[var_currentRow].append(element)
      } else {
        var_currentRow = var_currentRow + 1
        if (var_currentRow >= var_limitRowsNumber) {
          break
        }
        var_rows_data.append([element])
        var_remainingWidth = var_availableWidth
      }

      var_remainingWidth = var_remainingWidth - (elementSizeWidth + var_spacing)
    }

    return var_rows_data
  }

  private func ht_getTextWidth(text: String) -> CGFloat {
    let font = UIFont.systemFont(ofSize: 10) // 设置字体大小
    let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
    paragraphStyle.alignment = .left
    let attributes: [NSAttributedString.Key: Any] = [
      .font: font,
      .paragraphStyle: paragraphStyle
    ]
    let options: NSStringDrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]
    let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: 0)
    let boundingRect = text.boundingRect(with: size, options: options, attributes: attributes, context: nil)
    return ceil(boundingRect.width) + 16 * 2 // 添加左右边距
  }
}
